package vcproj2cmake.reader;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import vcproj2cmake.Configuration;
import vcproj2cmake.Filter;
import vcproj2cmake.Project;
import vcproj2cmake.References;

import jtools.files.XMLReader;

public class VCPROJReader {


	
	public static void main(String[] arg){
		try {
			new VCPROJReader().readVcProjFile(new File("../irrlicht/source/irrlicht/Irrlicht9.0.vcproj"));
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public Project readVcProjFile(File file) throws SAXException, IOException, ParserConfigurationException{
		XMLReader reader = new XMLReader();
		reader.parseFile(file.toString());
		
		Project proj = new Project();
		proj.projFile = file;
		Node projNode = reader.findNodes("VisualStudioProject").item(0);
		proj.Name = reader.getValue(projNode.getAttributes().getNamedItem("Name"));
		proj.ProjectGUID = reader.getValue(projNode.getAttributes().getNamedItem("ProjectGUID"));
		
		System.out.println("Projekt: " + proj.Name + "; ProjectGUID: " +proj.ProjectGUID);
		
		NodeList configurationList = reader.findNodes("Configuration");
		ArrayList<Configuration> confList = new ArrayList<Configuration>();
		
		for (int i = 0; i < configurationList.getLength(); i++){
			Node xmlConf = configurationList.item(i);
			if (xmlConf == null) continue;
			Configuration conf = new Configuration();
			proj.configurations.add(conf);
			confList.add(conf);
			String n = reader.getValue(xmlConf.getAttributes().getNamedItem("Name"));
			conf.name = getConfigName(n);
			conf.target = getConfigTarget(n);
			conf.ConfigurationType = Integer.parseInt(reader.getValue(xmlConf.getAttributes().getNamedItem("ConfigurationType")));
			
			System.out.println("Found Configuration: "+conf.name);
			conf.outputDir = reader.getValue(xmlConf.getAttributes().getNamedItem("OutputDirectory"));
			conf.intermediateDirectory = reader.getValue(xmlConf.getAttributes().getNamedItem("IntermediateDirectory"));
			
			NodeList toolList = reader.findNodes(xmlConf, "Tool");
			for (int j = 0; j < toolList.getLength(); j++){
				Node toolNode = toolList.item(j);
				String s = reader.getValue(toolNode.getAttributes().getNamedItem("Name"));
				if (s.equals("VCPreBuildEventTool")){
					s = reader.getValue(toolNode.getAttributes().getNamedItem("CommandLine"));
					conf.preBuildEvent = s;
					System.out.println(s);
				}else if (s.equals("VCCLCompilerTool")){
					s = reader.getValue(toolNode.getAttributes().getNamedItem("AdditionalIncludeDirectories"));
					conf.AdditionalIncludeDirectories = s; System.out.println("AdditionalIncludeDirectories : " + s);
					s = reader.getValue(toolNode.getAttributes().getNamedItem("PreprocessorDefinitions"));
					conf.PreprocessorDefinitions = s; System.out.println("PreprocessorDefinitions : "+s);
					s = reader.getValue(toolNode.getAttributes().getNamedItem("MinimalRebuild"));
					if (s != null && s.equals("true"))
						conf.MinimalRebuild = true; 
					else
						conf.MinimalRebuild = false;
					s = reader.getValue(toolNode.getAttributes().getNamedItem("BasicRuntimeChecks"));
					if (s != null) conf.BasicRuntimeChecks = Integer.parseInt(s);
					s = reader.getValue(toolNode.getAttributes().getNamedItem("RuntimeLibrary"));
					if (s != null) conf.RuntimeLibrary = Integer.parseInt(s);
					s = reader.getValue(toolNode.getAttributes().getNamedItem("WarningLevel"));
					if (s != null) conf.WarningLevel = Integer.parseInt(s);
					s = reader.getValue(toolNode.getAttributes().getNamedItem("DebugInformationFormat"));
					if (s != null) conf.DebugInformationFormat = Integer.parseInt(s);
					s = reader.getValue(toolNode.getAttributes().getNamedItem("DisableSpecificWarnings"));
					if (s != null) {conf.DisableSpecificWarnings = s;System.out.println("DisableSpecificWarnings :" + s);}
				}else if (s.equals("VCLinkerTool")){
					s = reader.getValue(toolNode.getAttributes().getNamedItem("AdditionalDependencies"));
					if (s != null) {conf.AdditionalDependencies = s;System.out.println(s);}
					s = reader.getValue(toolNode.getAttributes().getNamedItem("LinkIncremental"));
					if (s != null) {conf.LinkIncremental = Integer.parseInt(s);}
					s = reader.getValue(toolNode.getAttributes().getNamedItem("AdditionalLibraryDirectories"));
					if (s != null) {conf.AdditionalLibraryDirectories = s;}
					s = reader.getValue(toolNode.getAttributes().getNamedItem("GenerateDebugInformation"));
					if (s != null) {if (s.equals("true")) conf.GenerateDebugInformation = true; else conf.GenerateDebugInformation = false;}
				}	 
			}
		}
		
		NodeList refList = reader.findNodes(projNode, "ProjectReference");
		for (int j = 0; j < refList.getLength(); j++){
			Node xmlRef = refList.item(j);
			References ref = new References();
			proj.references.add(ref);
			ref.ReferencedProjectIdentifier = reader.getValue(xmlRef.getAttributes().getNamedItem("ReferencedProjectIdentifier"));
			ref.RelativePathToProject = reader.getValue(xmlRef.getAttributes().getNamedItem("RelativePathToProject"));
			System.out.println("Add Reference: "+ ref.ReferencedProjectIdentifier + " At: "+ref.RelativePathToProject);
		}
		
		
		NodeList filterList = reader.findNodes(projNode, "Filter");
		for (int j = 0; j <filterList.getLength(); j++){
			Node xmlFilter = filterList.item(j);
			String n2 = xmlFilter.getParentNode().getNodeName();
			if (n2.equals("Filter"))
				continue;
			Filter filter = readFilter(xmlFilter, reader, null);
			if (proj.filter.add(filter))
				System.out.println("Add Filter: "+xmlFilter.getNodeName());
		}
		
		proj.normalize();
		return proj;
	}
	
	private Filter readFilter(Node xmlFilter, XMLReader r, Filter parent) {
		String name = r.getAttributeValueAsString(xmlFilter, "Name");
		Filter filter = new Filter(name, parent);
		
		NodeList fileList = r.findNodes(xmlFilter, "File");
		for (int j = 0; j < fileList.getLength(); j++){
			Node xmlFile = fileList.item(j);
			String strFile = r.getValue(xmlFile.getAttributes().getNamedItem("RelativePath"));
			filter.addFile(strFile);
		}				
		
		NodeList filterList = r.findNodes(xmlFilter, "Filter");
		for (int i = 0; i < filterList.getLength(); i++)
			filter.addChild(readFilter(filterList.item(i), r, filter));
		
		return filter;
	}
	private String getConfigTarget(String n) {
		for (int i = 0; i < n.length(); i++)
			if (n.charAt(i) == '|'){
				return n.substring(i+1);
			}
		return n;
	}
	private String getConfigName(String n){
		for (int i = 0; i < n.length(); i++)
			if (n.charAt(i) == '|'){
				return n.substring(0, i);
			}
		return n;
	}
}
